// int转16进制补齐扩展
extension IntHexPadding on int {
  String toHex({int width = 2}) =>
      toRadixString(16).padLeft(width, '0').toUpperCase();
}

class PortTag {
  final int odfNo;
  final int trayNo;
  final int portNo;

  PortTag({required this.odfNo, required this.trayNo, required this.portNo});

  /// 编码为16进制紧凑字符串
  String encode() {
    final odfHex = odfNo.toHex();
    final trayHex = trayNo.toHex();
    final portHex = portNo.toHex();
    return 'A1$odfHex$trayHex$portHex';
  }

  /// 从16进制紧凑字符串解码
  static PortTag? decode(String epc) {
    final epcTrim = epc.trim().toUpperCase();
    if (!epcTrim.startsWith('A1')) return null;
    final padded = epcTrim.padRight(8, '0');
    try {
      final odfNo = int.parse(padded.substring(2, 4), radix: 16);
      final trayNo = int.parse(padded.substring(4, 6), radix: 16);
      final portNo = int.parse(padded.substring(6, 8), radix: 16);
      return PortTag(odfNo: odfNo, trayNo: trayNo, portNo: portNo);
    } catch (e) {
      return null;
    }
  }
}

class PatchCordTag extends PortTag {
  final int type; // 1=SC, 2=FC

  PatchCordTag({
    required super.odfNo,
    required super.trayNo,
    required super.portNo,
    required this.type,
  });

  /// 编码为16进制紧凑字符串
  @override
  String encode() {
    final odfHex = odfNo.toHex();
    final trayHex = trayNo.toHex();
    final portHex = portNo.toHex();
    final typeHex = type.toHex();
    return 'E1$odfHex$trayHex$portHex$typeHex';
  }

  /// 从16进制紧凑字符串解码
  static PatchCordTag? decode(String epc) {
    final epcTrim = epc.trim().toUpperCase();
    if (!epcTrim.startsWith('E1')) return null;
    // 补齐长度，不足补0
    final padded = epcTrim.padRight(10, '0');
    try {
      final odfNo = int.parse(padded.substring(2, 4), radix: 16);
      final trayNo = int.parse(padded.substring(4, 6), radix: 16);
      final portNo = int.parse(padded.substring(6, 8), radix: 16);
      var type = int.parse(padded.substring(8, 10), radix: 16);
      if (type == 0) {
        type = 1;
      }
      return PatchCordTag(
        odfNo: odfNo,
        trayNo: trayNo,
        portNo: portNo,
        type: type,
      );
    } catch (e) {
      return null;
    }
  }

  /// 类型转中文
  String get typeName {
    switch (type) {
      case 1:
        return 'SC';
      case 2:
        return 'FC';
      case 3:
        return 'SC+FC';
      default:
        return '未知';
    }
  }
}

dynamic decodeEPC(String epc) {
  final epcTrim = epc.trim().toUpperCase();
  if (epcTrim.startsWith('A1')) {
    return PortTag.decode(epcTrim);
  } else if (epcTrim.startsWith('E1')) {
    return PatchCordTag.decode(epcTrim);
  } else {
    return null;
  }
}

enum TagType {
  port,
  patchCord,
}

extension TagTypeExtension on TagType {
  String get name {
    switch (this) {
      case TagType.port:
        return '端口标签';
      case TagType.patchCord:
        return '插头标签';
    }
  }
}
